package intermouse;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * A pályát kezelő osztály, nyilvántartja az adott kört, a pályán lévő
 * szereplőket és felelős a körönkénti léptetésért.
 * 
 * @author Demény Fruzsina Gyöngyi
 * @version 1.0
 * @since 2013-03-23
 */
public class Level {

	/************* Attributes *****************/

	/**
	 * A köröket számolja, megadja a jelenlegi kör sorszámát.
	 */
	private int currentRound;
	/**
	 * A hangyákat tároló lista.
	 */
	private List<Ant> antList;
	/**
	 * A hangyára káros entitásokat tároló lista (hangyaleső, hangyaszsün,
	 * méreg).
	 */
	private List<Malicious> maliciousList;
	/**
	 * A hangyaboly referenciáját tárolja.
	 */
	private AntHill antHill;
	/**
	 * A mezők referenciáját tároló lista.
	 */
	List<Field> fields;
	
	private int levelWidth = 60, levelHeight = 40;
	
	/************* Constructors *****************/

	/**
	 * A Level osztály default konstruktora.
	 */
	public Level() {
		currentRound = 0;
		antList = new ArrayList<Ant>();
		maliciousList = new ArrayList<Malicious>();
		fields = new ArrayList<Field>();
		antHill = new AntHill();
		
		for(int i = 0; i < levelHeight; i++) //i a magasság (sorok száma)
		{ 
			for(int j = 0; j < levelWidth; j++)
			{		
					Field field=new Field();
					field.setCoords(i, j);
					for (int k = 0; k < 6; k++) //kitöltjük az adjacent fields-eket null-al egyelőre
						field.getAdjacentFields().add(null);
					fields.add(field); //és betesszük a fieldek közé lol
					
			}	
		}
			//  | -			    j:
			//	| :i   		- ----> +
			//	V +			
			
			//Itt töltjük ki az adjacent fields-et
			for(int i = 0; i < levelHeight; i++)  
			{
				for(int j = 0; j < levelWidth; j++) //oszlopok száma
				{
					if(i%2==0) //ha a sor páros (0. az első sor)
				{

					try { //levelHeight * Y KOORDINÁTA + X KOORDINÁTA
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(0, fields.get(levelWidth * (i-1) + (j+1)));
					} catch (IndexOutOfBoundsException e) { //gyors, és igénytelen fix (túlindexelsz, csak nem történik semmi)
					}

					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(1, fields.get(levelWidth * (i) + (j + 1)));
					} catch (IndexOutOfBoundsException e) {
					}

					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(2, fields.get(levelWidth * (i + 1) + (j + 1)));
					} catch (IndexOutOfBoundsException e) {
					}

					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(3, fields.get(levelWidth * (i + 1) + (j)));
					} catch (IndexOutOfBoundsException e) {
					}

					try { fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(4,fields.get(levelWidth * (i) + (j - 1)));
					} catch (IndexOutOfBoundsException e) {
					}

					try {fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(5, fields.get(levelWidth * (i - 1) + (j)));
					} catch (IndexOutOfBoundsException e) {
					}
				}
					else
 {
					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(0, fields.get(levelWidth * (i - 1) + (j)));
					} catch (IndexOutOfBoundsException e) {
					}

					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(1,	fields.get(levelWidth * (i)	+ (j+1)));
					} catch (IndexOutOfBoundsException e) {
					}

					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(2, fields.get(levelWidth * (i + 1) + (j)));
					} catch (IndexOutOfBoundsException e) {
					}

					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(3, fields.get(levelWidth * (i + 1) + (j - 1)));
					} catch (IndexOutOfBoundsException e) {
					}

					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(4,	fields.get(levelWidth * (i)	+ (j - 1)));
					} catch (IndexOutOfBoundsException e) {
					}

					try {
						fields.get(levelWidth * (i) + (j)).getAdjacentFields()
								.set(5, fields.get(levelWidth * (i - 1) + (j - 1)));
					} catch (IndexOutOfBoundsException e) {
					}
				}
			}
			}
				
			
		
	}

	/************* Getters *****************/

	/**
	 * @return Visszaadja a currentRound változó értékét, ami integer típusú.
	 */
	public int getCurrentRound() {
		System.out.println(">> Level.getCurrentRound() : int");
		System.out.println("<< return" + currentRound);
		return currentRound;
	}

	/************* Setters *****************/

	/**
	 * @param i
	 *            A currentRound változó új értéke.
	 */
	public void setCurrentRound(int i) {
		System.out.println(">> Level.setCurrentRound(i:int) : void");
		this.currentRound = i;
		System.out.println("<< return");
	}

	/**
	 * @param antHill
	 *            A hangyaboly referenciáját állítja be.
	 */
	public void setAntHill(AntHill antHill) {
		System.out.println(">> ::Level.setAntHill(antHill:AntHill) : void");
		this.antHill = antHill;
		System.out.println("<< return");
	}

	/************* Methods *****************/
	/**
	 * A pálya inicializálását végző függvény.
	 */
	public void init() {
		System.out.println(">> Main::Level.init() : void");
		
		
		
		//Fieldek létrehozása
		for(int i = 0; i < levelWidth; i++)
		{
			for(int j = 0; j < levelHeight; j++)
			{
				
				if (i == 20 && j == 37) fields.get(levelWidth * (i) + (j)).addFieldObject(new Stone());
				if (i == 25 && j == 30) fields.get(levelWidth * (i) + (j)).addFieldObject(new Stone());
				if (i == 51 && j == 20) fields.get(levelWidth * (i) + (j)).addFieldObject(new Stone());
				if (i == 9 && j == 2) fields.get(levelWidth * (i) + (j)).addFieldObject(new Stone());
				if (i == 1 && j == 14) fields.get(levelWidth * (i) + (j)).addFieldObject(new Stone());
				this.antHill = new AntHill();
				if (i == 5 && j == 5) fields.get(levelWidth * (i) + (j)).addFieldObject(this.antHill);
				Water w = new Water();
				if (i == 20 && j == 20) fields.get(levelWidth * (i) + (j)).addFieldObject(w);
				w.spreadWater(5);
				if (i == 54 && j == 14) fields.get(levelWidth * (i) + (j)).addFieldObject(new AntLion());
				if (i == 32 && j == 16) fields.get(levelWidth * (i) + (j)).addFieldObject(new AntLion());
				if (i == 11 && j == 34) fields.get(levelWidth * (i) + (j)).addFieldObject(new AntLion());
				if (i == 45 && j == 11) fields.get(levelWidth * (i) + (j)).addFieldObject(new AntLion());
				if (i == 22 && j == 41) fields.get(levelWidth * (i) + (j)).addFieldObject(new AntLion());
				
				if (i == 17 && j == 34) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 17 && j == 34) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 17 && j == 34) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 17 && j == 34) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 17 && j == 34) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 42 && j == 11) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 42 && j == 11) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 42 && j == 11) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 42 && j == 11) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 57 && j == 43) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 57 && j == 43) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 57 && j == 43) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 57 && j == 43) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 37 && j == 10) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 37 && j == 10) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 37 && j == 10) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				if (i == 37 && j == 10) fields.get(levelWidth * (i) + (j)).addFieldObject(new Food());
				
			}
		}
		
		
		
		
		
		System.out.println("<< return");
	}

	/**
	 * A körök lebonyolítását végzi, meghívja a szereplők beginRound()
	 * függvényeit.
	 * 
	 */
	public void makeStep() {
		System.out.println(">> Level.makeStep() : void");
		Iterator<Ant> it = antList.iterator();
		while (it.hasNext()) {
			Ant a = it.next();
			if (a.getDead())
				it.remove();
		}
		for (Field f : fields) {
			f.beginRound();
		}
		for (Ant a : antList) {
			a.beginRound();
		}
		for (Malicious m : maliciousList) {
			m.beginRound();
		}
		currentRound++;
		System.out.println("<< return");
	}

	/**
	 * A maliciousList listához hozzáad egy új elemet, amely Poison típusú.
	 * 
	 * @param f
	 *            A mező referenciáját adja meg, ahol a méreg elhelyezkedik.
	 */
	public void addPoison(Field f) {
		System.out.println(">> Level.addPosion(f:Field) : void");
		Poison p = new Poison();
		p.spawn(f);
		maliciousList.add(p);
		System.out.println("<< return");
	}

	/**
	 * Az antList listához hozzáadja a paraméterként kapott hangyát.
	 * 
	 * @param ant
	 *            A hangya referenciája, amit a listához kell adni.
	 */
	public void addAnt(Ant ant) {
		System.out.println(">> Level.addAnt(ant:Ant) : void");
		antList.add(ant);
		System.out.println("<< return");
	}
}
